﻿using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace HttpRequest.Helper
{
    public class GzipHelper
    {
        /// <summary>
        /// 压缩
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static byte[] CompressString(string text)
        {
            byte[] buffer = Encoding.UTF8.GetBytes(text);
            using (var memoryStream = new MemoryStream())
            {
                using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress, true))
                {
                    gzipStream.Write(buffer, 0, buffer.Length);
                }
                return memoryStream.ToArray();
            }
        }

        /// <summary>
        /// 解压
        /// </summary>
        /// <param name="compressedBytes"></param>
        /// <returns></returns>
        public static string DecompressString(byte[] compressedBytes)
        {
            using (var memoryStream = new MemoryStream(compressedBytes))
            {
                using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Decompress))
                {
                    using (var reader = new StreamReader(gzipStream))
                    {
                        return reader.ReadToEnd();
                    }
                }
            }
        }

        /// <summary>
        /// 数据压缩 new
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string Compress(string source)
        {
            var bytes = Encoding.UTF8.GetBytes(source);
            using (var compressedStream = new MemoryStream())
            {
                using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
                {
                    zipStream.Write(bytes, 0, bytes.Length);
                }
                return Convert.ToBase64String(compressedStream.ToArray());
            }

        }
        /// <summary>
        /// 数据解压 new
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        public static string Decompress(string result)
        {

            var bytes = Convert.FromBase64String(result);
            using (var compressStream = new MemoryStream(bytes))
            {
                using (var zipStream = new GZipStream(compressStream, CompressionMode.Decompress))
                {
                    using (var resultStream = new MemoryStream())
                    {
                        zipStream.CopyTo(resultStream);
                        return Encoding.UTF8.GetString(resultStream.ToArray());

                    }
                }
            }
        }

        /// <summary>
        /// TripleDES加密，key长度为16
        /// </summary>
        /// <param name="plainText">明文</param>
        /// <param name="key">密钥</param>
        /// <returns>TripleDES加密结果</returns>
        public static string EncryptData(string plainText, string key)
        {
            //TripleDESCryptoServiceProvider Tripledes = new TripleDESCryptoServiceProvider();
            ////Tripledes.Mode = CipherMode.ECB;
            ////Tripledes.Padding = PaddingMode.PKCS7;
            //byte[] b_input = Encoding.UTF8.GetBytes(plainText);
            //byte[] b_key = Encoding.UTF8.GetBytes(key);

            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            tdes.Key = Encoding.UTF8.GetBytes(key);
            tdes.Mode = CipherMode.ECB;
            tdes.Padding = PaddingMode.PKCS7;

            ICryptoTransform cryptoTransform = tdes.CreateEncryptor();
            byte[] bytes = Encoding.UTF8.GetBytes(plainText);
            byte[] encrypted = cryptoTransform.TransformFinalBlock(bytes, 0, bytes.Length);

            Console.WriteLine("Encrypted: " + BitConverter.ToString(encrypted).Replace("-", ""));


            //MemoryStream ziptempStream = new MemoryStream();
            //using (var zipStream = new GZipStream(ziptempStream, CompressionMode.Compress))
            //{
            //    zipStream.Write(encrypted.ToArray(), 0, encrypted.ToArray().Length);
            //}


            //byte[] byteData = Encoding.UTF8.GetBytes(input);
            using (var memoryStream = new MemoryStream())
            {
                using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress))
                {
                    gzipStream.Write(encrypted, 0, encrypted.Length);
                }
                //return memoryStream.ToArray();
                return Convert.ToBase64String(memoryStream.ToArray());
            }

        }

        /// <summary>
        /// TripleDES解密，key长度为16
        /// </summary>
        /// <param name="input">TripleDES加密的结果</param>
        /// <param name="key">密钥</param>
        /// <returns>TripleDES解密结果</returns>
        public static string DecryptData(string input, string key)
        {
            TripleDESCryptoServiceProvider Tripledes = new TripleDESCryptoServiceProvider();
            byte[] b_input = Convert.FromBase64String(input);
            byte[] b_key = Encoding.UTF8.GetBytes(key);
            MemoryStream tempStream = new MemoryStream();
            //rgbKey即用于对称算法的密钥、rgbIV即用于对称算法的初始化向量，这里均使用b_key
            CryptoStream encStream = new CryptoStream(tempStream, Tripledes.CreateDecryptor(b_key, b_key), CryptoStreamMode.Write);
            encStream.Write(b_input, 0, b_input.Length);
            encStream.FlushFinalBlock();
            return Encoding.UTF8.GetString(tempStream.ToArray());
        }

        /// <summary>
        /// 加密+压缩base64
        /// </summary>
        /// <param name="pToEncrypt"></param>
        /// <param name="sKey"></param>
        /// <returns></returns>
        public static string TripleDESEncryptAndGizpReturnBase64(string pToEncrypt, string sKey)
        {
            try
            {
                sKey = sKey.Substring(0, 24);
                TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
                des.Key = Encoding.ASCII.GetBytes(sKey);
                des.IV = new byte[] { 0, 00, 00, 00, 00, 00, 00, 00, };// ASCIIEncoding.ASCII.GetBytes(sKey.Substring(0, 8));
                des.Mode = CipherMode.ECB;
                des.Padding = PaddingMode.PKCS7;
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);

                byte[] inputByteArray = Encoding.UTF8.GetBytes(pToEncrypt);
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock(); ;
                StringBuilder ret = new StringBuilder();
                foreach (byte b in ms.ToArray())
                {
                    ret.AppendFormat("{0:X2}", b);
                }
                ret.ToString();
                var aaa = ret.ToString();
                byte[] retbyte = Encoding.UTF8.GetBytes(ret.ToString());
                using (var memoryStream = new MemoryStream())
                {
                    using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress))
                    {
                        gzipStream.Write(ms.ToArray(), 0, ms.ToArray().Length);
                    }
                    //return memoryStream.ToArray();
                    return Convert.ToBase64String(memoryStream.ToArray());
                }

                //return ret.ToString();
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        /// <summary>
        /// base64解密+Gzip解压+3DES解密
        /// </summary>
        /// <param name="pToEncrypt"></param>
        /// <param name="sKey"></param>
        /// <returns></returns>
        public static string DeTripleDESEncryptAndGizpReturnBase64(string pToEncrypt, string sKey)
        {
            var bytes = Convert.FromBase64String(pToEncrypt);
            using (var compressStream = new MemoryStream(bytes))
            {
                using (var zipStream = new GZipStream(compressStream, CompressionMode.Decompress))
                {
                    using (var resultStream = new MemoryStream())
                    {
                        zipStream.CopyTo(resultStream);

                        sKey = sKey.Substring(0, 24);
                        TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
                        des.Key = Encoding.ASCII.GetBytes(sKey);
                        des.IV = new byte[] { 0, 00, 00, 00, 00, 00, 00, 00, };// ASCIIEncoding.ASCII.GetBytes(sKey.Substring(0, 8));
                        des.Mode = CipherMode.ECB;
                        des.Padding = PaddingMode.PKCS7;
                        MemoryStream ms = new MemoryStream();
                        CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);

                        cs.Write(resultStream.ToArray(), 0, resultStream.ToArray().Length);
                        cs.FlushFinalBlock();

                        return Encoding.UTF8.GetString(ms.ToArray());
                        //return Encoding.UTF8.GetString(resultStream.ToArray());

                    }
                }
            }
        }
    }
}
